package com.owc.service.impl.app;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.owc.common.enums.ExceptionEnum;
import com.owc.common.enums.OrderType;
import com.owc.common.enums.ProductType;
import com.owc.common.enums.StatusEnum;
import com.owc.common.exception.BadRequestException;
import com.owc.common.lock.Lock;
import com.owc.common.tool.BeanUtils;
import com.owc.common.tool.DateUtils;
import com.owc.dao.OrderMapper;
import com.owc.dao.ProductMapper;
import com.owc.dao.TokenBalanceMapper;
import com.owc.domain.BaseResult;
import com.owc.domain.DO.BuyModel;
import com.owc.domain.dto.*;
import com.owc.domain.entity.Order;
import com.owc.domain.entity.Product;
import com.owc.domain.entity.TokenBalance;
import com.owc.domain.vo.app.BuyProductVo;
import com.owc.filter.content.SecurityContextHolder;
import com.owc.service.app.InvestmentService;
import com.owc.service.app.OrderService;
import com.owc.service.app.WalletService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

/**
 * @Author xiaom
 * @Date 2020/2/24 14:05
 * @Version 1.0.0
 * @Description <>
 **/
@Service
@Slf4j
public class InvestmentServiceImpl implements InvestmentService {

    @Resource
    private ProductMapper productMapper;

    @Autowired
    private WalletService walletService;
    @Autowired
    private OrderService orderService;

    @Override
    public BaseResult<List<ProductDTO>> productList(Integer pageIndex,Integer pageSize) {
        PageHelper.startPage(pageIndex,pageSize);
        List<ProductDTO> list = productMapper.selectAll();
        PageInfo<ProductDTO> pageInfo = new PageInfo<>(list);
        return BaseResult.success(list,pageInfo.getTotal());
    }

    @Override
    public ProductDetailDTO getById(Long id) {
        return productMapper.selectDetailByProduceId(id);
    }

    @Override
    public ProductBuyDTO buyDetail(Long id) {
        //Fetch product detail info. Choose token.
        Product product = productMapper.selectByPrimaryKey(id);
        if(product == null){
            throw new BadRequestException(ExceptionEnum.INVALID_PRODUCT_ERR);
        }
        if(product.getTokenId() == null){
            throw new BadRequestException(ExceptionEnum.INVALID_PRODUCT_ERR);
        }

        ProductBuyDTO dto = BeanUtils.transformFrom(product,ProductBuyDTO.class);
        if(dto == null){
            throw new BadRequestException(ExceptionEnum.UNKNOWN_ERR);
        }
        //Query Product investment token. Fetch token balance.
        BalanceDTO balanceDTO = walletService.getTokenBalance(product.getTokenId());
        dto.setBalance(balanceDTO.getBalance());
        dto.setBuyQuota(product.getBuyMax());

        return dto;
    }

    /**
     * 购买产品
     * 1 检查购买金额是否超过最大额度
     * 2 检查余额是否充足
     * 3 生成购买订单记录
     * 4 减少余额
     * @param buyProductVo  购买参数
     */
    @Override
    public BuyProductDTO buyProduct(BuyProductVo buyProductVo) throws Exception {

        ProductDetailDTO productDetail = getById(buyProductVo.getProductId());
        if(productDetail == null){
            throw new BadRequestException(ExceptionEnum.INVALID_PRODUCT_ERR);
        }

        if(productDetail.getBuyMax().compareTo(buyProductVo.getBuyAmount()) < 0){
            throw new BadRequestException(ExceptionEnum.BEYOND_MAX_LIMIT);
        }

        //Check product last new status.
        if(!ProductType.ONLINE_TYPE.getType().equals(productDetail.getStatus())){
            throw new BadRequestException(ExceptionEnum.PRODUCT_INVALID_ERR);
        }

        BigDecimal balance = walletService.getTokenBalanceByUserId(productDetail.getTokenId(),buyProductVo.getUserId()).getBalance();
        if(balance.compareTo(buyProductVo.getBuyAmount()) < 0){
            log.error("购买理财产品：可用余额不足。当前余额:[{}] 需要余额:[{}]",balance,buyProductVo.getBuyAmount());
            throw new BadRequestException(ExceptionEnum.BALANCE_BELOW_ERR);
        }

        BuyModel buyModel = BeanUtils.transformFrom(buyProductVo, BuyModel.class);
        if(buyModel == null){
            throw new BadRequestException(ExceptionEnum.UNKNOWN_ERR);
        }

        //验证通过,生成订单记录
        return new BuyProductDTO(orderService.generateOrder(buyModel));
    }


}
